/**
 * 
 */
package com.demo2do.fms.admin.security;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.demo2do.fms.admin.entity.security.Login;
import com.demo2do.fms.admin.service.authority.OrganizationService;
import com.demo2do.fms.admin.service.authority.ResourceService;
import com.demo2do.fms.admin.service.authority.UserService;
import com.demo2do.fms.entity.authority.User;

/**
 * @author downpour
 */
public class ApplicationAuthenticationProvider implements UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(ApplicationAuthenticationProvider.class);
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private ResourceService resourceService;
    
    @Autowired
    private OrganizationService organizationService;
    
    /* (non-Javadoc)
     * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        
        // ======= initialize other user properties =======
        User user = userService.load(username);
        
        if(user == null) {
            throw new UsernameNotFoundException("未能找到用户");
        }

        logger.info("ApplicationAuthenticationProvider#loadUserByUsername() - principal [" + user.getLoginName() + "] is found to login. ");
        
        // 1. construct Login by Principal
        Login login = new Login(user);
        
        // 2. initialize role based resources
        Map<String, List<String>> resources= resourceService.list(user);
        if(MapUtils.isNotEmpty(resources)) {
            login.initResources(resources);
        }
        
        // 3. init user_supplier_relation ( organization ) List<Long>
        List<Long> orgIds = organizationService.listUserOrganization(user);
        if(CollectionUtils.isNotEmpty(orgIds)){
            login.initOrgIds(orgIds);
        }
        
        return login;
        
    }

}
